#pragma once 

/*******************************************************************************
* Using template pattern
*******************************************************************************/

#include "types.h"

//class CDC;
class CLocalPane;

class CElement
{
public:
	CElement(CLocalPane* pSquarePane, 
             CPoint firstPoint, 
             UINT nSquareWidth,
             UINT nStateCount, 
		     COLORREF color, 
             ElementState state, 
             SpinMode mode);

	CElement::~CElement(void);

	// Action
	bool Spin();
	bool GoDown();
	bool GoLeft();
	bool GoRight();

    bool CanSpin();
    bool CanGoDown();
    bool CanGoLeft();
    bool CanGoRight();

	// Draw and fill
	void Draw();
	void Draw(CDC* pDC);
	void Draw(CDC* pDC, CPoint pntFirst, double fScale = 1.0);

	void Fill();
	void Fill(CDC* pDC);
	void Fill(CDC* pDC, CPoint pntFirst, double fScale = 1.0);

	// Attributes
	SpinMode GetSpinMode() const;
	void SetSpinMode(SpinMode mode);

    CPoint GetFirstPoint() const;
    void SetFirstPoint(const CPoint& pnt);

	ElementState GetNextState() const;
	const SquareList& GetSquareList() const;

	UINT GetStateCount() const;
	CRect GetOutlineRect() const;
	
    UINT GetSquareWidth() const;
    void SetSquareWidth(UINT nSquareWidth);

private:
	void CalcSpinSquareList(SquareList& listSquare) const;
	void CalcGoDownSquareList(SquareList& squareList) const;
	void CalcGoLeftSquareList(SquareList& squareList) const;
	void CalcGoRightSquareList(SquareList& squareList) const;

	/**********************************************************************
    * This is the only function you should rewrite
	* Construct square list of an element
	* @1    [in]	element state
	* @2	[in]	the topleft point of outline rect
	* @3	[out]	square list
	**********************************************************************/
	virtual void ConstructSquareList(ElementState state, CPoint pntFirstPoint, UINT nSquareWidth, SquareList& listSquare) const = 0;

protected:
	CLocalPane*	m_pSquarePane;
	CPoint			m_pntFirstPoint;
    UINT            m_nSquareWidth;
	ElementState	m_CurrentState;
	SpinMode		m_CurrentSpinMode;
	UINT			m_nStateCount;
	SquareList		m_listSquare;
	COLORREF	    m_ElementColor;
};